home *** CD-ROM | disk | FTP | other *** search
/ CyberMycha 2005 May / CyberMycha 05-2005 (Poland).bin / Immortal / cotndemo.exe / Data1.cab / nvidiahardwareshadowmap.fx < prev    next >
Encoding:
Text File  |  2004-11-16  |  9.4 KB  |  277 lines

  1. // Adapted from NVidia's HardwareShadowMap example, from NVSDK 7.0
  2. //-----------------------------------------------------------------------------
  3.  
  4. texture ShadowMap;
  5. texture ShadowColorBuffer;
  6. texture ModelTexture;
  7.  
  8. //-----------------------------------------------------------------------------
  9.  
  10. float4x4 WorldViewProj;
  11. float4x4 WorldIT;
  12. float4x4 TexTransform;
  13. float3 sunlight_direction;
  14. float4 sunlight_color;
  15. float4x4 light_MVP;
  16. float zbias;
  17. float3 moonlight_direction;
  18. float4 moonlight_color;
  19. float4 material_diffuse_color;
  20. float4 material_ambient_color;
  21. float4 global_ambient_color;
  22. float one_minus_shadowalpha;
  23. float shadowalpha;
  24. float fogEnd;
  25. float fogEndMinusStartInv; // Calculated by C++: 1 / (FogEnd - FogStart)
  26.  
  27. //-----------------------------------------------------------------------------
  28.  
  29. struct VS_INPUT_TER {
  30.     float3 Position  : POSITION;
  31.     float3 Normal    : NORMAL;
  32.     float4 Color0    : COLOR0;
  33.     float2 TexCoord0 : TEXCOORD0;
  34. };
  35.  
  36. struct VS_OUTPUT_TER {
  37.     float4 Position  : POSITION;
  38.     float4 TexCoord0 : TEXCOORD0;
  39.     float4 TexCoord1 : TEXCOORD1;
  40.     float2 TexCoord2 : TEXCOORD2;
  41.     float4 Color0    : COLOR0;
  42.     float  Fog       : FOG;
  43. };
  44.  
  45. struct VS_INPUT_OBJ {
  46.     float4 Position  : POSITION;
  47.     float3 Normal    : NORMAL;
  48.     float4 TexCoord0 : TEXCOORD0;
  49. };
  50.  
  51. struct VS_OUTPUT_OBJ {
  52.     float4 Position  : POSITION;
  53.     float4 TexCoord0 : TEXCOORD0;
  54.     float4 TexCoord1 : TEXCOORD1;
  55.     float2 TexCoord2 : TEXCOORD2;
  56.     float2 TexCoord3 : TEXCOORD3;
  57.     float4 Color0    : COLOR0;
  58.     float  Fog       : FOG;
  59. };
  60.  
  61. //-----------------------------------------------------------------------------
  62.  
  63. sampler ShadowMapSampler = sampler_state
  64. {
  65.     Texture = <ShadowMap>;
  66.     MinFilter = Linear;  
  67.     MagFilter = Linear;
  68.     MipFilter = None;
  69.     AddressU  = Clamp;
  70.     AddressV  = Clamp;
  71.     AddressW  = Clamp;
  72. };
  73.  
  74. sampler ShadowColorBufferSampler = sampler_state
  75. {
  76.     Texture = <ShadowColorBuffer>;
  77.     MinFilter = Linear;  
  78.     MagFilter = Linear;
  79.     MipFilter = None;
  80.     AddressU  = Clamp;
  81.     AddressV  = Clamp;
  82.     AddressW  = Clamp;
  83. };
  84.  
  85. sampler ModelTextureSampler = sampler_state
  86. {
  87.     Texture = <ModelTexture>;
  88.     MinFilter = Linear;  
  89.     MagFilter = Linear;
  90.     MipFilter = Linear;
  91. };
  92.  
  93. //-----------------------------------------------------------------------------
  94.  
  95. // vertex shader to combine shadow map texture with model drawing to create shadows
  96. // this shader is used when drawing objects.
  97. VS_OUTPUT_OBJ CombineShadowObjectsVS(VS_INPUT_OBJ IN)
  98. {
  99.     VS_OUTPUT_OBJ OUT;
  100.  
  101.     OUT.Position = mul(IN.Position, WorldViewProj);
  102.  
  103.     OUT.Fog = clamp(((fogEnd - OUT.Position.w) * fogEndMinusStartInv), 0.0f, 1.0f);
  104.  
  105.     OUT.TexCoord2 = IN.TexCoord0;
  106.  
  107.     // TexTransform = light MVP matrix * texture adjustment matrix
  108.     // transform model-space vertex position to light-space:
  109.      OUT.TexCoord0 = mul(IN.Position, TexTransform);
  110.     OUT.TexCoord0.z += zbias; // add z-bias to prevent inappropriate self-shadowing 
  111.     OUT.TexCoord1 = mul(IN.Position, TexTransform);
  112.  
  113.     float sun_intensity = dot(IN.Normal, sunlight_direction);
  114.  
  115.     // If the polygon is not facing the light, do *NOT* shadow it.
  116.     OUT.TexCoord3 = sun_intensity;
  117.  
  118.     float4 moonDiffuseColor = max(0, dot(IN.Normal, moonlight_direction)); // face doesn't receive moonlight if it's not facing the moon
  119.     moonDiffuseColor *= moonlight_color * material_diffuse_color;
  120.  
  121.     float4 DiffuseColor =  max(0, sun_intensity); // face doesn't receive sunlight if it's not facing the sun
  122.     DiffuseColor *= sunlight_color * material_diffuse_color; //!NOTE what about alpha?
  123.     
  124.     DiffuseColor += moonDiffuseColor; // add moonlight color
  125.     OUT.Color0 = DiffuseColor + global_ambient_color * material_ambient_color;
  126.     //!NOTE: no incoming vertex color
  127.  
  128.     return OUT;
  129. }
  130.  
  131. //-----------------------------------------------------------------------------
  132.  
  133. // pixel shader to combine shadow map texture with model drawing to create shadows
  134. // used when drawing objects
  135. float4 CombineShadowObjectsPS(VS_OUTPUT_OBJ IN) : COLOR 
  136. {
  137.     float myColorBuffer = tex2Dproj(ShadowColorBufferSampler, IN.TexCoord1 ).r;
  138.     
  139.     // Note that shadow should range from one_minus_shadowalpha (full shadow) to 1 (no shadow).
  140.     float4 shadow;
  141.     if (myColorBuffer == 1 )
  142.     {
  143.         // If myColorBuffer is 1, then that part of the shadow map hasn't been written to, so there is no shadow.
  144.         // Note: this is a hack to get around the fact that NVidia's shadow buffer doesn't clamp correctly.
  145.         shadow = float4(1,1,1,1);
  146.     }
  147.     else if (IN.TexCoord3.x <= 0)
  148.     {
  149.         // If IN.TexCoord3.x < 0, then the triangle is facing away from the light
  150.         // Tried a bunch of different things here, including setting the pixel to be shadowed, and fading
  151.         // in a shadow depending on the value in IN.TexCoord3.x.  None of these are perfect, since
  152.         // the shadow doesn't quite match up with the regular object diffuse & ambient shading.
  153.         // If you set it to no shadow, then it looks weird when a figure is completely in a building's shadow.
  154.         // Half of the figure will be shadowed, and half won't.  Other than that, it looks good & it's fast.
  155.         shadow = float4(1,1,1,1); // no shadow
  156.     }
  157.     else
  158.     {
  159.         // Get the shadow value from the shadow map buffer and convert it to the correct range.
  160.         shadow = tex2Dproj(ShadowMapSampler, IN.TexCoord0 ) * shadowalpha + one_minus_shadowalpha;
  161.     }
  162.     shadow.a = 1; // shadow alpha = 1.0 (ie shadow doesn't reduce alpha)
  163.     
  164.     float4 color = tex2D(ModelTextureSampler, IN.TexCoord2) * IN.Color0 * shadow;
  165.     return color;
  166. }
  167.  
  168.  
  169. //-----------------------------------------------------------------------------
  170.  
  171. // vertex shader to combine shadow map texture with model drawing to create shadows
  172. // this shader is used when drawing the terrain.
  173. VS_OUTPUT_TER CombineShadowTerrainVS(VS_INPUT_TER IN)
  174. {
  175.     VS_OUTPUT_TER OUT;
  176.  
  177.     // transform model-space vertex position to screen space:
  178.     OUT.Position = mul(float4(IN.Position, 1), WorldViewProj);
  179.  
  180.     OUT.Fog = clamp(((fogEnd - OUT.Position.w) * fogEndMinusStartInv), 0.0f, 1.0f);
  181.  
  182.     OUT.TexCoord2 = IN.TexCoord0;
  183.     
  184.     // transform model-space vertex position to light-space:
  185.     OUT.TexCoord0 = mul(float4(IN.Normal, 1), TexTransform); // Normal is actually world position untransformed by C++
  186.     OUT.TexCoord1 = mul(float4(IN.Normal, 1), TexTransform);
  187.     
  188.     OUT.Color0 = IN.Color0;
  189.  
  190.     return OUT;
  191. }
  192.  
  193. //-----------------------------------------------------------------------------
  194.  
  195. // pixel shader to combine shadow map texture with model drawing to create shadows
  196. // used when drawing terrain
  197. float4 CombineShadowTerrainPS(VS_OUTPUT_TER IN) : COLOR 
  198. {
  199.     // If myColorBuffer is 1, then that part of the shadow map hasn't been written to, so there is no shadow.
  200.     // Note: this is a hack to get around the fact that NVidia's shadow buffer doesn't clamp correctly.
  201.     float myColorBuffer = tex2Dproj(ShadowColorBufferSampler, IN.TexCoord1 ).r;
  202.  
  203.     float4 shadow;
  204.  
  205.     // Note that shadow should range from one_minus_shadowalpha (full shadow) to 1 (no shadow).
  206.  
  207.     shadow = (myColorBuffer == 1 ) ? 
  208.                     float4(1,1,1,1) : 
  209.                     tex2Dproj(ShadowMapSampler, IN.TexCoord0 ) * shadowalpha + one_minus_shadowalpha;
  210.     shadow.a = 1; // shadow alpha = 1.0 (ie shadow doesn't reduce alpha)
  211.  
  212.     float4 color = tex2D(ModelTextureSampler, IN.TexCoord2) * IN.Color0 * shadow;
  213.     return color;
  214. }
  215.  
  216. //-----------------------------------------------------------------------------
  217.  
  218. technique CombineShadowMapWithTerrain
  219. {
  220.     pass P0
  221.     {
  222.         VertexShader = compile vs_1_1 CombineShadowTerrainVS();
  223.         PixelShader = compile ps_2_0 CombineShadowTerrainPS();
  224.  
  225.         Texture[0] = <ShadowMap>;
  226.         Texture[1] = <ShadowColorBuffer>;
  227.         Texture[2] = <ModelTexture>;        
  228.         TexCoordIndex[0] = 0;
  229.         TexCoordIndex[1] = 1;
  230.         TexCoordIndex[2] = 2;
  231.         TextureTransformFlags[0] = Projected | Count4; // maybe not necessary for PS 2.0?
  232.         TextureTransformFlags[1] = Projected | Count4;
  233.         TextureTransformFlags[2] = Disable;
  234.         
  235. //        ZEnable          = True;
  236. //        AlphaBlendEnable = False;
  237. //        Lighting         = False;
  238. //        CullMode         = None;
  239.     
  240. //        TexCoordIndex[0] = 0;
  241. //        TexCoordIndex[1] = 1;
  242. //        TextureTransformFlags[0] = Projected; //!NOTE always need these? See NVidia guy's note
  243. //        TextureTransformFlags[1] = Projected;
  244.     }
  245. }
  246.  
  247. //-----------------------------------------------------------------------------
  248.  
  249. technique CombineShadowMapWithObjects
  250. {
  251.     pass P0
  252.     {
  253.         VertexShader = compile vs_1_1 CombineShadowObjectsVS();
  254.         PixelShader = compile ps_2_0 CombineShadowObjectsPS();
  255.         
  256.         Texture[0] = <ShadowMap>;
  257.         Texture[1] = <ShadowColorBuffer>;
  258.         Texture[2] = <ModelTexture>;        
  259.         TexCoordIndex[0] = 0;
  260.         TexCoordIndex[1] = 1;
  261.         TexCoordIndex[2] = 2;
  262.         TextureTransformFlags[0] = Projected | Count4;
  263.         TextureTransformFlags[1] = Projected | Count4;
  264.         TextureTransformFlags[2] = Disable;
  265.  
  266. //        ZEnable          = True;
  267. //        AlphaBlendEnable = False;
  268. //        Lighting         = False;
  269. //        CullMode         = None;
  270.     
  271. //        TexCoordIndex[0] = 0;
  272. //        TexCoordIndex[1] = 1;
  273. //        TextureTransformFlags[0] = Projected; //!NOTE always need these? See NVidia guy's note
  274. //        TextureTransformFlags[1] = Projected;
  275.     }
  276. }
  277.